package br.unesp.rc.rafaelt.model.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;

import br.unesp.rc.rafaelt.model.dao.AbstractDao;

public abstract class AbstractDaoImpl<PK extends Serializable, E> implements AbstractDao<PK, E> {

    @PersistenceContext
    protected EntityManager em;

    private final Class<E> entityClass;

    @SuppressWarnings("unchecked")
    public AbstractDaoImpl() {
        super();
        this.entityClass = (Class<E>) ((ParameterizedType) getClass().
                getGenericSuperclass()).getActualTypeArguments()[1];
    }

    public E findById(final PK id) {
        return (E) em.find(entityClass, id);
    }

    public void remove(final E entity) {
        em.remove(entity);
    }

    public void persist(final E entity) {
        em.persist(entity);
    }

    public E merge(final E entity) {
        return (E) em.merge(entity);
    }

    public void flush() {
        em.flush();
    }
    
    public TypedQuery<E> createTypedQuery(final String query) {
        return em.createQuery(query, entityClass);
    }
    

    public TypedQuery<E> createNamedTypedQuery(final String namedQuery) {
        return em.createNamedQuery(namedQuery, entityClass);
    }

    public void setParameters(final Query query, final Object[] params) {
        if (query != null && params != null) {
            for (int i = 1; i <= params.length; i++) {
                query.setParameter(i, params[i - 1]);
            }
        }
    }

}
